#!/usr/bin/env python3
# coding:utf-8

import os
import sys
import shutil
import time
import logging
import multiprocessing
import platform
import argparse

import subprocess
from subprocess import check_call, call

bin_path = os.path.dirname(os.path.realpath(sys.argv[0]))
lib_path = os.path.join(bin_path, 'lib')
sys.path.append(lib_path)
import vmseed


WORKSPACE       = os.path.dirname(os.path.abspath(__file__))
cwd             = os.getcwd()

config_path     = os.path.join(WORKSPACE, 'config')
shell_path      = os.path.join(WORKSPACE, 'shell_script')
date            = time.strftime("%Y%m%d", time.localtime())

logger = logging.getLogger('image_build')
handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(name)s: %(message)s'))
handler.setLevel(logging.WARNING)
logger.addHandler(handler)


# move file from source to dest
def move_file(file_path, dest):
    if not os.path.exists(dest):
        os.makedirs(dest)

    if os.path.exists(file_path):
        shutil.move(file_path, dest)


def make_sqfs(version, build_id, url, arch):
    sqfs_name = 'OpenCloudOS-Stream-%s-%s-%s.sqfs' % (version, build_id, arch)
    if arch == 'x86_64':
        rpm_list = os.path.join(config_path, 'base_rpmlist_x86_64')
    elif arch == 'aarch64':
        rpm_list = os.path.join(config_path, 'base_rpmlist_aarch64')
    elif arch == 'loongarch64':
        rpm_list = os.path.join(config_path, 'base_rpmlist_loongarch64')

    mksqfs_path = os.path.join(shell_path, 'mksqfs.sh')
    shutil.copy2(mksqfs_path, cwd)
    shutil.copy2(rpm_list, cwd)
    # subprocess.call("sed -i 's/SQFS_NAME/%s/g' ./mksqfs.sh" % (sqfs_name), shell=True)
    root_dir = os.path.join(cwd, 'sqfsroot-tmp')
    data = ""
    repo, repofrompath = handle_urls(url)
    with open('./mksqfs.sh', 'r') as f:
        for line in f:
            if 'ROOTPATH' in line or 'URL' in line or 'REPO' in line:
                line = line.replace('ROOTPATH', root_dir)
                line = line.replace('URL', repofrompath)
                line = line.replace('REPO', repo)
            data += line

    with open('./mksqfs.sh', 'w') as p:
        p.write(data)
    ret = subprocess.call("./mksqfs.sh %s" % (arch), shell=True)
    sqfs_operations(sqfs_name)
    if ret != 0:
        sys.exit(1)
    return sqfs_name


def sqfs_operations(sqfs_name):
    subprocess.call("echo 'PermitRootLogin yes' >> sqfsroot-tmp/etc/ssh/sshd_config", shell=True)

    grubcfg_path = os.path.join(config_path, 'grub.cfg')
    shutil.copy2(grubcfg_path, cwd + '/sqfsroot-tmp/boot/efi/EFI/opencloudos/grub.cfg')
    
    default_target_path = os.path.join('sqfsroot-tmp', 'etc/systemd/system/default.target')
        # unlink any links already in place
    if os.path.islink(default_target_path):
        os.unlink(default_target_path)
    # symlink the selected target
    selected_target_path = os.path.join('/usr/lib/systemd/system', 'multi-user.target')
    print("Linking %s as systemd default target.", selected_target_path)
    os.symlink(selected_target_path, default_target_path)

    default_localtime_path = os.path.join('sqfsroot-tmp', 'etc/localtime')
    if os.path.islink(default_localtime_path):
        os.unlink(default_localtime_path)
    selected_localtime_path = "../usr/share/zoneinfo/Asia/Beijing"
    os.symlink(selected_localtime_path, default_localtime_path)

    redhat_repo_path = os.path.join('sqfsroot-tmp', 'etc/yum.repos.d/redhat.repo')
    if os.path.exists(redhat_repo_path):
        os.remove(redhat_repo_path)

    kernel_sysconfig_path = os.path.join(config_path, 'kernel')
    target_kernel_sysconfig_path = os.path.join(f'{cwd}/sqfsroot-tmp', 'etc/sysconfig/kernel')
    shutil.copy2(kernel_sysconfig_path, target_kernel_sysconfig_path)

    do_some_clean(os.path.join(cwd, 'sqfsroot-tmp'))

    subprocess.call("mksquashfs sqfsroot-tmp %s -comp xz -b 262144" % (sqfs_name), shell=True)

# organize the url into repo 
def handle_urls(urls):
    repo = ""
    repofrompath = ""
    for i in range(len(urls)):
        tmp_repo = "[build%d]\nname=build%d\nbaseurl=%s\ngpgcheck=0\n" %(i, i, urls[i])
        repo += tmp_repo
        tmp_repo = " --repofrompath ocs%d,%s " %(i, urls[i])
        repofrompath += tmp_repo
    return repo, repofrompath

def make_qcow2(sqfs_file, version, build_id, arch):
    filename = 'OpenCloudOS-Stream-%s-%s-%s.qcow2' % (version, build_id, arch)
  
    if not os.path.exists(sqfs_file):
        logger.error("sqfs does not exist")
        sys.exit(1)

    if os.path.exists(filename):
        print("%s exists, please remove it and try again" % filename)
        sys.exit(3)

    os.rename(vmseed.make_ext4_qcow2(10, arch), filename)
    time.sleep(2)
    current_dir = os.getcwd()
    print("current work dir: %s" % (current_dir))
    nbdfile = vmseed.mount_qcow2(filename, arch)
    devpath = "/dev/" + nbdfile

    if arch == 'x86_64':
        partpath = ["\/dev\/mapper\/" + nbdfile + "p1"]
    elif arch == 'aarch64':
        partpath = ["\/dev\/mapper\/" + nbdfile + "p1", "\/dev\/mapper\/" + nbdfile + "p2"]
    elif arch == 'loongarch64':
        partpath = ["\/dev\/mapper\/" + nbdfile + "p1", "\/dev\/mapper\/" + nbdfile + "p2"]

    multiprocessing_run(extract_file_to, (sqfs_file, vmseed.MOUNT_POINT), 
                        devpath, "extract "+sqfs_file)
    multiprocessing_run(vmseed.mount_proc_dev_sys, (), 
                        devpath, "mount proc, dev, sys")
    multiprocessing_run(work_in_newroot, (vmseed.MOUNT_POINT, partpath, 'Dis@init3'),
                        devpath, "configure new root")
    multiprocessing_run(grub2_install, (vmseed.MOUNT_POINT, devpath),
                        devpath, "install grub2")

    add_new_user(vmseed.MOUNT_POINT, 'Opencloudos+23')

    multiprocessing_run(relabel_selinux, (vmseed.MOUNT_POINT,),
                        devpath, "relabel img selinux context")
    multiprocessing_run(vmseed.umount_proc_dev_sys, (), 
                        devpath, "umount proc, dev, sys")

    print("checkout to current work dir: %s" % (current_dir))
    os.chdir(current_dir)

    do_some_clean(os.path.join(cwd, vmseed.MOUNT_POINT))

    subprocess.call("sync && sync && sleep 10s", shell=True)

    vmseed.detach_nbd(devpath)

    # calculate the sha256 of the qcow2 file using sha256sum and subprocess, sum write into a file
    if os.path.exists(filename):
        sha256sum = subprocess.Popen(["sha256sum", filename], stdout=subprocess.PIPE)
        sha256sum = sha256sum.communicate()[0].decode().split()[0]
        with open(filename + ".sha256", "w") as f:
            f.write(f"{sha256sum}  {filename}")
    move_file(filename, cwd + '/releases/')
    move_file(filename + ".sha256", cwd + '/releases/')
    

def extract_file_to(filename, dirname):
    print("Extract %s to %s" % (filename, dirname))

    filename = os.path.realpath(filename)
    
    call(["unsquashfs", "-f", "-d", dirname, filename])
    if not os.path.exists(os.path.join(dirname, 'proc')):
        try:
            os.makedirs(os.path.join(dirname, 'proc'))
        except OSError:
            print('Error:fail to mkdir /proc !!!')
    if not os.path.exists(os.path.join(dirname, 'dev')):
        try:
            os.makedirs(os.path.join(dirname, 'dev'))
        except OSError:
            print('Error:fail to mkdir /dev !!!')
    if not os.path.exists(os.path.join(dirname, 'sys')):
        try:
            os.makedirs(os.path.join(dirname, 'sys'))
        except OSError:
            print('Error:fail to mkdir /sys !!!')
    os.chdir(dirname)
    return


def work_in_newroot(dirname, partpath, vm_password):
    grub_file = os.path.join(dirname, "etc/default/grub")
    grub2_conf = os.path.join(dirname, "boot/grub2/grub.cfg")
    fstab_conf = os.path.join(config_path, "fstab")
    grub_conf = os.path.join(config_path, "grub")
    # get UUID
    print("get UUID")
    uuid = []
    if arch == 'x86_64':
        cmd = 'blkid | grep ' + partpath[0] + ' | cut -d \'\"\' -f 2'
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
        p.wait()
        uuid.append(p.stdout.read().strip().decode())
    elif arch == 'aarch64':
        # something like: vda1 vfat FAT32 {UUID}
        cmd = 'lsblk ' + partpath[0] + ' -f | grep vfat | awk \'{ print $4 }\''
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
        p.wait()
        uuid.append(p.stdout.read().strip().decode())
        # something like: nbd1p2 xfs {UUID}
        cmd = 'lsblk ' + partpath[1] + ' -f | grep xfs | awk \'{ print $3 }\''
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
        p.wait()
        uuid.append(p.stdout.read().strip().decode())
    elif arch == 'loongarch64':
        # something like: vda1 vfat FAT32 {UUID}
        cmd = 'lsblk ' + partpath[0] + ' -f | grep vfat | awk \'{ print $4 }\''
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
        p.wait()
        uuid.append(p.stdout.read().strip().decode())
        # something like: nbd1p2 xfs {UUID}
        cmd = 'lsblk ' + partpath[1] + ' -f | grep xfs | awk \'{ print $3 }\''
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
        p.wait()
        uuid.append(p.stdout.read().strip().decode())

    # make grub
    shutil.copy2(grub_conf, grub_file)

    if arch == 'aarch64':
        check_call(["sed", "-i", "-e", r"s/intel_idle.max_cstate=1 intel_pstate=disable//", grub_file]) 
    if arch == 'loongarch64':
        check_call(["sed", "-i", "-e", r"s/intel_idle.max_cstate=1 intel_pstate=disable//", grub_file]) 

    check_call(["chroot", dirname, "grub2-editenv", "create"])
    check_call(["chroot", dirname, "grub2-set-default", "0"])
    subprocess.call("chmod -x %s/etc/grub.d/30_os-prober" % dirname, shell = True)
    check_call(["chroot", dirname, "grub2-mkconfig", "-o", "/boot/grub2/grub.cfg"])
    subprocess.call("chmod +x %s/etc/grub.d/30_os-prober" % dirname, shell = True)
    if arch == 'loongarch64':
        print("cp -a /boot/efi/EFI/opencloudos/grubloongarch64.efi to /boot/efi/EFI/BOOT/BOOTLOONGARCH64.EFI")
        check_call(["chroot", dirname, "cp", "-a", "/boot/efi/EFI/opencloudos/grubloongarch64.efi", "/boot/efi/EFI/BOOT/BOOTLOONGARCH64.EFI"])

    loader_conf = os.path.join(dirname, "boot/loader/entries/*.conf")
    # subprocess.call("sed -i 's/options .*$/options $kernelopts/' %s" % (loader_conf), shell=True)
    check_call(["sed", "-i", "-r", "-e", r's/^\s*timeout([ =])[0-9]+/timeout\10/', grub_file])
    check_call(["sed", "-i", "s/GRUB_DISABLE_LINUX_UUID/#&/", grub_file])

    fstab_file = os.path.join(dirname, "etc/fstab")
    shutil.copy2(fstab_conf, fstab_file)
    check_call(["sed", "-i", "s/sda/vda/g", fstab_file])
    # mount by UUID for fstab
    if arch == 'x86_64':
        check_call(["sed", "-i", "s/\/dev\/vda1/UUID=%s/" % (uuid[0]), fstab_file])
    elif arch == 'aarch64':
        check_call(["sed", "-i", "s/\/dev\/vda1/UUID=%s/" % (uuid[1]), fstab_file])
        check_call(["sed", "-i", "s/#\/dev\/vda2/UUID=%s/" % (uuid[0]), fstab_file])
    elif arch == 'loongarch64':
        check_call(["sed", "-i", "s/\/dev\/vda1/UUID=%s/" % (uuid[1]), fstab_file])
        check_call(["sed", "-i", "s/#\/dev\/vda2/UUID=%s/" % (uuid[0]), fstab_file])

    time.sleep(2)
    check_call(["umount", os.path.join(dirname, "dev")])
    call(["chroot", dirname, "mknod", "-m", "0640", "/dev/vda", "b", "253", "0"])
    call(["chroot", dirname, "mknod", "-m", "0640", "/dev/vda1", "b", "253", "1"])
    call(["chroot", dirname, "mknod", "-m", "0640", "/dev/vdb", "b", "253", "16"])
    call(["chroot", dirname, "mknod", "-m", "0640", "/dev/vdb1", "b", "253", "17"])
    check_call(["mount", "-o", "bind", "/dev", os.path.join(dirname, "dev")])
    # end

    print('empty /etc/machine-id')
    subprocess.call('echo -n > '+dirname+'/etc/machine-id', shell = True)
    
    # /tmp do not use tmpfs
    print('disable tmpfs for /tmp')
    subprocess.call(f'chroot {dirname} systemctl mask tmp.mount', shell=True)

    print('change password')
    p = subprocess.Popen(["chroot", dirname, "passwd"], stdin=subprocess.PIPE)
    pwd = "%s\n%s\n" % (vm_password, vm_password)
    print("change passwd to:" + pwd)
    p.communicate(pwd.encode())
    p.wait()
    time.sleep(1)

    
def grub2_install(dirname, devpath):
    if arch == 'x86_64':
        print("dirname %s  devpath %s" % (dirname, devpath))
        call(["chroot", dirname, "grub2-install", devpath])
    # as we set selinux to permissive, so need to fixfiles of selinux context
    call(["chroot", dirname, "fixfiles", "-F", "onboot"])


def add_new_user(dirname, vm_password):
    print('add user: opencloudos')
    call(["chroot", dirname, "useradd", "opencloudos"])
    p = subprocess.Popen(["chroot", dirname, "passwd", "opencloudos"], stdin=subprocess.PIPE)
    pwd = "%s\n%s\n" % (vm_password, vm_password)
    print("change passwd to:" + pwd)
    p.communicate(pwd.encode())
    p.wait()
    time.sleep(1)
    call(["chroot", dirname, "usermod", "-aG", "wheel", "opencloudos"])


def relabel_selinux(dirname):
    '''
    relabel need in selinux permissive or enforce to execute
    '''
    print('relabel selinux context in image:')
    # umount proc and sys
    cmd = 'umount %s'% os.path.join(dirname, 'proc')
    call(cmd, shell=True)
    cmd = 'umount %s'% os.path.join(dirname, 'sys')
    call(cmd, shell=True)

    # bind host proc and sys, 
    # we need use the runtime which already has selinux labels
    cmd = 'mount --bind /proc %s' % os.path.join(dirname, 'proc')
    call(cmd, shell=True)
    cmd = 'mount --bind /sys %s' % os.path.join(dirname, 'sys')
    call(cmd, shell=True)

    # bind /sys/fs/selinux
    cmd = 'mount -t selinuxfs -o defaults selinuxfs %s' % os.path.join(dirname, 'sys/fs/selinux')
    call(cmd, shell=True)

    # call restorecon
    cmd = "chroot %s restorecon -ir /boot /dev /etc /lib64 \
    /root /usr/lib /usr/lib64 /var /usr " % dirname
    check_call(cmd, shell=True)

    # call restorecon, set a task to correct label and reboot when first boot
    cmd = "chroot %s restorecon -i /" % dirname
    check_call(cmd, shell=True)

    # umount proc and sys
    cmd = 'umount -l %s' % os.path.join(dirname, 'proc')
    call(cmd, shell=True)
    cmd = 'umount -l %s'% os.path.join(dirname, 'sys')
    call(cmd, shell=True)

    # mount proc and sys
    cmd = 'mount -t proc proc %s' % os.path.join(dirname, 'proc')
    call(cmd, shell=True)
    cmd = 'mount -t sysfs sysfs %s' % os.path.join(dirname, 'sys')
    call(cmd, shell=True)
    

def multiprocessing_run(target, args, devpath, msg):
    print(msg)
    p = multiprocessing.Process(target=target, args=args)
    p.start()
    p.join()
    if p.exitcode != 0:
        print(msg + " failed")
        vmseed.detach_nbd(devpath)
        sys.exit(5)


def make_docker(sqfs, version, build_id, arch):
    tar_final_name = 'OpenCloudOS-Stream-%s-%s-%s.tar' % (version, build_id, arch)

    # check require tool
    check_docker_file_exist(sqfs)
    check_docker_dir_exist()
    check_docker_unsquashfs_tool()

    # unsquanfs
    unsquashfs_to_docker_dir(sqfs)
    mount_to_docker_dir()

    # remove kernel and rpm
    remove_kernel_of_docker()
    remove_rpm_of_docker()
    disable_service_of_docker()

    # unmount
    umount_from_docker_dir()

    # clean dir
    clean_docker_dir()

    # produce docker
    make_docker(tar_final_name)
    print('make docker successful!\n\n')


def check_docker_file_exist(sqfs):
    if os.path.isfile(sqfs):
        print('sqfs file is exist')
    else:
        print('Error:sqfs file is not exist')
        exit(1)


def check_docker_dir_exist():
    if os.path.isdir('ocs-docker'):
        try:
            subprocess.check_call('rm -rf ocs-docker', shell=True)
        except OSError:
            print('Error:fail to delete ocs-docker !!!')
            exit(1)

    try:
        os.mkdir('ocs-docker')
    except OSError:
        print('Error:fail to mkdir ocs-docker')
        exit(1)


def check_docker_unsquashfs_tool():
    p = subprocess.Popen("rpm -q squashfs-tools", shell=True, stdout=subprocess.PIPE)
    sqfs_version = p.stdout.read().decode()

    if "4." in sqfs_version:
        print('squashfs-tool is already')
    else:
        print('Error:squashfs-tools is not install or version is wrong')
        print('try \"yum install -y squashfs-tools\"')
        exit(1)


def unsquashfs_to_docker_dir(sqfs):
    print('unsquashfs start')
    subprocess.call("unsquashfs -f -d ocs-docker " + sqfs, shell=True)
    print('unsquashfs finish')


def mount_to_docker_dir():
    print('mount /dev devpts proc sysfs to ocs-docker')
    subprocess.call('mount -o bind /dev ocs-docker/dev', shell=True)
    subprocess.call('mount -o bind /run ocs-docker/run', shell=True)
    subprocess.call('mount -t devpts devpts ocs-docker/dev/pts', shell=True)
    subprocess.call('mount -t proc proc ocs-docker/proc', shell=True)
    subprocess.call('mount -t sysfs sysfs ocs-docker/sys', shell=True)
    print('mount done')


def remove_kernel_of_docker():
    print('remove kernel rpms')
    # if kernel_version == 'tkernel2':
    print('start remove kernel rpms')
    subprocess.call('chroot ocs-docker rpm -qa | grep kernel | chroot ocs-docker xargs rpm -e --nodeps', shell=True)


# grub2 crash mandb centos docker qemu firmware firewalld
def remove_rpm_of_docker():
    print('remove kexec-tools mcelog microcode_ctl')
    subprocess.call('chroot ocs-docker rpm -qa | grep kexec-tools | chroot ocs-docker xargs rpm -e --nodeps', \
    shell=True)
    subprocess.call('chroot ocs-docker rpm -qa | grep mcelog | chroot ocs-docker xargs rpm -e --nodeps', shell=True)
    subprocess.call('chroot ocs-docker rpm -qa | grep microcode_ctl | chroot ocs-docker xargs rpm -e --nodeps', \
    shell=True)
    subprocess.call('chroot ocs-docker rpm -qa | grep firmware | chroot ocs-docker xargs rpm -e --nodeps', shell=True)
    subprocess.call('chroot ocs-docker rpm -qa | grep grub2 | chroot ocs-docker xargs rpm -e --nodeps', shell=True)

    subprocess.call('chroot ocs-docker rpm -qa | grep man-db | chroot ocs-docker xargs rpm -e --nodeps', shell=True)
    subprocess.call('chroot ocs-docker rpm -qa | grep man-pages | chroot ocs-docker xargs rpm -e --nodeps', shell=True)
    subprocess.call('chroot ocs-docker rpm -qa | grep vim-common | chroot ocs-docker xargs rpm -e --nodeps', shell=True)


def disable_service_of_docker():
    print('disable some services')
    subprocess.call('chroot ocs-docker chkconfig network off', shell=True)
    subprocess.call('chroot ocs-docker chkconfig irqaffinity off', shell=True)
    subprocess.call('chroot ocs-docker chkconfig openibd off', shell=True)
    subprocess.call('chroot ocs-docker systemctl disable console-getty.service', shell=True)
    subprocess.call('chroot ocs-docker systemctl mask getty@tty1.service', shell=True)
    subprocess.call('chroot ocs-docker chkconfig rename_netifs off', shell=True)


def umount_from_docker_dir():
    print('umount ocs-docker\'s /dev/pts /dev /proc /sys')
    subprocess.call('umount ocs-docker/dev/pts', shell=True)
    subprocess.call('umount ocs-docker/dev', shell=True)
    subprocess.call('umount ocs-docker/run', shell=True)
    subprocess.call('umount ocs-docker/proc', shell=True)
    subprocess.call('umount ocs-docker/sys', shell=True)
    print('umount done')


def clean_docker_dir():
    print('empty /etc/machine-id')
    subprocess.call('echo -n > ocs-docker/etc/machine-id', shell = True)
    print('clean .bash_history .viminfo /tmp/* /run/* getty.target.wants/*')
    subprocess.call('rm -rf ocs-docker/root/.bash_history', shell=True)
    subprocess.call('rm -rf ocs-docker/root/.viminfo', shell=True)
    subprocess.call('rm -rf ocs-docker/tmp/*', shell=True)
    subprocess.call('rm -rf ocs-docker/usr/local/TsysAgent.tar.gz', shell=True)
    subprocess.call('rm -rf ocs-docker/run/*', shell=True)
    subprocess.call('rm -rf ocs-docker/var/cache/yum/*', shell=True)
    subprocess.call('rm -rf ocs-docker/etc/systemd/system/getty.target.wants/*', shell=True)
    print('clean done')


def make_docker(new_tar_name):
    print('make docker')
    os.chdir('./ocs-docker')
    subprocess.call('tar cf ../'+new_tar_name+' *', shell=True)
    os.chdir('../')


def make_mini_docker_image(version, build_id, url, arch):
    print('make mini-docker image')
    docker_image_name = 'OpenCloudOS-Stream-%s-%s-mini-docker-%s' % (version, build_id, arch)
    mini_docker_path = os.path.join(shell_path, 'build_mini-docker_image.sh')
    shutil.copy2(mini_docker_path, cwd)
    data = ""

    _, repofrompath = handle_urls(url)

    with open('./build_mini-docker_image.sh', 'r') as f:
        for line in f:
            if 'URL' in line:
                line = line.replace('URL', repofrompath)
            data += line
    with open('./build_mini-docker_image.sh', 'w') as p:
        p.write(data)
    ret = subprocess.call(f'./build_mini-docker_image.sh {docker_image_name}', shell=True)
    if ret != 0:
        sys.exit(1)
    filename = docker_image_name + '.tar'
    if os.path.exists(filename):
        sha256sum = subprocess.Popen(["sha256sum", filename], stdout=subprocess.PIPE)
        sha256sum = sha256sum.communicate()[0].decode().split()[0]
        with open(filename + ".sha256", "w") as f:
            f.write(f"{sha256sum}  {filename}")
    move_file(filename, cwd + '/releases/')
    move_file(filename + ".sha256", cwd + '/releases/')


def do_some_clean(dirname):
    if dirname == '/' or dirname == '':
        print('dirname is / or empty.')
        return
    if not os.path.exists(dirname):
        print('dirname does not exist.')
        return

    subprocess.call(f'echo -n > {dirname}/etc/machine-id', shell = True)
    subprocess.call(f'rm -rf {dirname}/var/lib/dbus/machine-id', shell = True)

    subprocess.call(f'rm -rf {dirname}/root/.bash_history', shell=True)
    subprocess.call(f'rm -rf {dirname}/root/.viminfo', shell=True)
    subprocess.call(f'rm -rf {dirname}/tmp/*', shell=True)
    subprocess.call(f'rm -rf {dirname}/run/*', shell=True)
    subprocess.call(f'rm -rf {dirname}/var/cache/yum/*', shell=True)
    subprocess.call(f'rm -rf {dirname}/var/log/dnf.log*', shell=True)
    subprocess.call(f'rm -rf {dirname}/var/log/dnf.rpm.log', shell=True)
    subprocess.call(f'rm -rf {dirname}/var/log/dnf.librepo.log*', shell=True)
    subprocess.call(f'rm -rf {dirname}/var/log/hawkey.log', shell=True)
    subprocess.call(f'rm -rf {dirname}/var/cache/dnf/*', shell=True)
    subprocess.call(f'echo -n > {dirname}/etc/resolv.conf', shell = True)
    subprocess.call(f'echo "# preserve comment to avoid generating conf.save" > {dirname}/etc/resolv.conf', shell = True)
    subprocess.call("find "+ dirname +"/var/log -type f | while read f;do echo ''>$f ;done", shell=True)
    print('clean done')


def parse_option():
    parser = argparse.ArgumentParser()
    parser.add_argument('-v', '--version', dest='version', help='specific the build release version')
    parser.add_argument('-b', '--buildid', dest='buildid', help='specific the build ID')
    parser.add_argument('-u', '--url', action='append', dest='urls', help='specific the repo url')

    args = parser.parse_args()
    return args


if __name__ == '__main__':
    # we need root priviledge to run the script
    if os.geteuid() != 0:
        print('You need to have root privileges to run this script')
        sys.exit(1)

    arch = platform.machine()
    args = parse_option()
    build_id = args.buildid

    sqfs = make_sqfs(args.version, build_id, args.urls, arch)
    make_qcow2(sqfs, args.version, build_id, arch)
    # make_docker(sqfs, args.version, build_id, arch)
    make_mini_docker_image(args.version, build_id, args.urls, arch)
